/*
 * Copyright 2011 jmarsden.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cc.plural.jsonij.jpath.functions;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import cc.plural.jsonij.JSONParser;
import cc.plural.jsonij.Value;
import cc.plural.jsonij.JSONParser.StatefullValue;
import cc.plural.jsonij.jpath.JPathParserException;
import cc.plural.parser.ParserException;

/**
 *
 * @author jmarsden
 */
public class FunctionArgument {

    public static enum ARGUMENT_TYPE {

        ATTRIBUTE,
        VALUE
    }
    ARGUMENT_TYPE type;

    public ARGUMENT_TYPE getType() {
        return type;
    }

    public void setType(ARGUMENT_TYPE type) {
        this.type = type;
    }

    public static class AttributeArgument extends FunctionArgument {

        String attributeName;

        public AttributeArgument(String attributeName) {
            this.attributeName = attributeName;
            this.type = ARGUMENT_TYPE.ATTRIBUTE;
        }

        public String getAttributeName() {
            return attributeName;
        }

        public void setAttributeName(String attributeName) {
            this.attributeName = attributeName;
        }
               
        @Override
        public String toString() {
            return String.format("@.%s", attributeName);
        }

    }

    public static class ValueArgument extends FunctionArgument {

        Value value;

        public ValueArgument(Value value) {
            this.value = value;
            this.type = ARGUMENT_TYPE.VALUE;
        }

        public Value getValue() {
            return value;
        }

        public void setValue(Value value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return value.toJSON();
        }
    }
    
    public static FunctionArgument[] parseStringToArguments(String string) throws IOException, JPathParserException {
        FunctionArgument[] argumentArray = null;
        List<FunctionArgument> argumentList = new ArrayList<FunctionArgument>();
        int stringLength = string.length();
        int i=0;
        while(i < stringLength-1) {
            char c=string.charAt(i);
            while(i<stringLength-1 && c==' ') {
                c=string.charAt(++i);
            }
            if(c == '@') {
                if(i < stringLength-1) {
                    c=string.charAt(++i);
                }
                if(c == '.') {
                    StringBuilder attributebuilder = new StringBuilder();
                    if(i < stringLength-1) {
                        c=string.charAt(++i);
                    }
                    while(c != ',') {
                        attributebuilder.append(c);
                        if(i < stringLength-1) {
                            c=string.charAt(++i);
                        } else {
                            break;
                        }
                    }
                    if(i < stringLength-1) {
                        c=string.charAt(++i);
                    } else {
                        break;
                    }
                    AttributeArgument argument = new AttributeArgument(attributebuilder.toString().trim()); 
                    argumentList.add(argument);
                } else {
                    throw new JPathParserException("functionPredicateAttributeParse", 0, 0, '.');
                }
            } else {
                try {
                    JSONParser valueParser = new JSONParser();
                    StatefullValue value = valueParser.parseStatefullValue(string, i);
                    i = value.getReader().getIndex();
                    ValueArgument argument = new ValueArgument(value.getValue()); 
                    argumentList.add(argument); 
                } catch (ParserException ex) {
                    throw new JPathParserException("functionPredicateValueParse", 0, 0, ex);
                }
            } 
        }
        argumentArray = new FunctionArgument[argumentList.size()];
        argumentList.toArray(argumentArray);
        return argumentArray;
    }
}
